一、為什麼刪除功能也需要謹慎設計?
前幾天,我們已經完成病患資料的新增、查詢和修改。
接下來就是 CRUD 中最後一個基本操作:Delete,也就是刪除資料。
在一般的資料管理系統中,刪除功能很常見。例如,測試時建立了不需要的假資料,就可以將它移除。
但在醫療資訊系統中,資料刪除需要更加謹慎。真實病歷可能涉及法規、稽核、保存期限與醫療責任,不能因為使用者按下按鈕,就直接永久刪除。
因此,今天先以虛構的測試資料練習 SQL 與程式流程。
二、認識 DELETE 語法
MySQL 可以使用 DELETE 刪除資料。
例如:
DELETE FROM patient
WHERE id = 1;
這段語法代表刪除 patient 資料表中,編號為 1 的紀錄。
如果只想先確認資料,可以在刪除前執行:
SELECT *
FROM patient
WHERE id = 1;
確認選中的紀錄是預期的測試資料,再進行刪除。
最重要的觀念仍然是:
刪除操作必須有明確的條件,不能隨意省略 WHERE。
如果省略條件,就可能刪除整張資料表中的所有紀錄。
三、使用 JDBC 執行刪除
建立 TestPatientDelete.java:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import util.DBConnection;
public class TestPatientDelete {
public static void main(String[] args) {
String sql =
"DELETE FROM patient WHERE id = ?";
try (
Connection conn = DBConnection.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)
) {
ps.setInt(1, 1);
int rows = ps.executeUpdate();
if (rows > 0) {
System.out.println("刪除成功!");
} else {
System.out.println("找不到這筆資料。");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
這段程式和前一天的修改程式很像,主要差別在於 SQL。
String sql = "DELETE FROM patient WHERE id = ?";
我們透過問號代表要刪除的病患編號,再使用:
ps.setInt(1, 1);
將第一個參數設定為 1。
最後執行:
int rows = ps.executeUpdate();
如果有一筆紀錄被刪除,通常會得到 1;如果沒有符合條件的資料,就會得到 0。
四、讓使用者透過網頁刪除資料
接著,我們建立一個 Servlet,讓使用者可以從表單送出欲刪除的病患編號。
建立 PatientDeleteServlet.java:
package servlet;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import util.DBConnection;
@WebServlet("/patient/delete")
public class PatientDeleteServlet extends HttpServlet {
@Override
protected void doPost(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String idText = request.getParameter("id");
try {
int id = Integer.parseInt(idText);
if (id <= 0) {
response.sendError(
HttpServletResponse.SC_BAD_REQUEST,
"病患編號不正確"
);
return;
}
String sql =
"DELETE FROM patient WHERE id = ?";
try (
Connection conn = DBConnection.getConnection();
PreparedStatement ps =
conn.prepareStatement(sql)
) {
ps.setInt(1, id);
int rows = ps.executeUpdate();
if (rows > 0) {
response.sendRedirect(
request.getContextPath() + "/patients"
);
} else {
response.sendError(
HttpServletResponse.SC_NOT_FOUND,
"找不到這筆病患資料"
);
}
}
} catch (NumberFormatException e) {
response.sendError(
HttpServletResponse.SC_BAD_REQUEST,
"病患編號必須是整數"
);
} catch (SQLException e) {
throw new ServletException("刪除資料失敗", e);
}
}
}
這裡使用 doPost(),代表刪除資料是透過 POST 請求處理,而不是單純打開一個網址就執行刪除。
不過,使用 POST 本身並不代表操作一定安全。正式系統仍然需要驗證登入身分、確認使用者是否有刪除權限,並實作 CSRF 防護。
五、建立刪除表單
我們可以先用一個簡單的 JSP 來練習:
<%@ page contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
這裡的 confirm() 會在送出表單前顯示確認視窗。
如果使用者選擇取消,表單就不會送出。
但也要注意,這只是使用者介面的提醒,並不是安全防護。真正的權限檢查必須在伺服器端進行。
六、為什麼正式醫療系統不能隨意刪除病歷?
今天雖然使用 DELETE 練習資料刪除,但正式醫療系統可能採用不同的資料生命週期管理方式,例如:
例如,系統可能設計一個 status 欄位,讓測試紀錄或特定資料被標記為停用,而不是立即從資料庫刪除。
但是否適用,仍然要依照實際需求與法規決定。
七、確認刪除結果
刪除操作完成後,可以回到 MySQL 執行:
SELECT *
FROM patient
WHERE id = 1;
如果查詢結果沒有資料,就代表目前找不到這個編號的紀錄。
請只對自己建立的虛構測試資料進行練習,避免誤刪需要保留的紀錄。
今日小結
今天完成了病患資料刪除功能,學會:
Day 21 完成!
現在我們已經學過新增、查詢、修改和刪除。下一篇要讓病患清單更實用:加入搜尋功能,讓使用者可以快速找到需要的測試資料。
參考資料:Oracle Java Tutorials:Using Prepared Statements